﻿using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Controls;
using System.Xml;
using System.Windows.Media;
using System.Windows;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Threading;

namespace GreetingWCFService
{
    [DataContract()]
    public class Captcha
    {
        private static readonly Random lRandom = new Random(Thread.CurrentThread.ManagedThreadId);
        //const string characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        private const string characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private string letters = string.Empty;
        private string xaml = string.Empty;

        public Captcha(int length, Dictionary<string, XDocument> dict)
        {
            letters = GetRandomLetters(length);
            xaml = GetXAML(dict);
        }

        private string GetXAML(Dictionary<string, XDocument> dict)
        {
            StringBuilder tempXAML = new StringBuilder();            
            tempXAML.Append("<Grid xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">");
            tempXAML.Append("<StackPanel Orientation=\"Horizontal\">");

            try
            {
                foreach (var letter in letters)
                {
                    XmlReader xmlReader = dict[letter.ToString()].CreateReader();
                    Canvas canvas = (Canvas)System.Windows.Markup.XamlReader.Load(xmlReader);
                    canvas.Margin = new Thickness((double)1, (double)1, (double)1, (double)1);

                    UIElement child = canvas.Children[canvas.Children.Count - 1];
                    child.Opacity = lRandom.Next(10, 20);

                    CreateTransforms(canvas);

                    tempXAML.Append(System.Windows.Markup.XamlWriter.Save(canvas));
                }

                XmlReader xmlLineReader = dict["line"].CreateReader();
                Canvas canvasLine = (Canvas)System.Windows.Markup.XamlReader.Load(xmlLineReader);
                canvasLine.SetValue(Canvas.LeftProperty, (double)0);
                canvasLine.SetValue(Canvas.TopProperty, (double)lRandom.Next(35, 40));

                CreateTransforms(canvasLine);

                tempXAML.Append("</StackPanel>");
                tempXAML.Append(System.Windows.Markup.XamlWriter.Save(canvasLine));                
                tempXAML.Append("</Grid>");

                return tempXAML.ToString();

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private static void CreateTransforms(UIElement uielement)
        {
            RotateTransform rotate = new RotateTransform();
            rotate.Angle = lRandom.Next(-15, 15);
            uielement.SetValue(UIElement.RenderTransformProperty, rotate);

            SkewTransform skew = new SkewTransform();
            skew.AngleX = lRandom.Next(-15, 15);
            skew.AngleY = lRandom.Next(-15, 15);
            uielement.SetValue(UIElement.RenderTransformProperty, skew);
        }

        public string Letters
        {
            get { return letters; }
        }

        [DataMember()]
        public string XAML
        {
            get { return xaml; }
            set { xaml = value; }
        }

        private string GetRandomLetters(int length)
        {
            StringBuilder buffer = new StringBuilder(length);
            for (int i = 0; i < length; i++)
            {
                int randomNumber = lRandom.Next(0, characters.Length);
                buffer.Append(characters, randomNumber, 1);
            }
            return buffer.ToString();
        }
    }
}